import User from "../../utils/user";
import msg from "../../utils/msg";
import { SignIn } from "../../utils/request/api";
import { Location, signDetail, SignParamActivity, SignParamCourse } from "./interface";
import { Course } from "../curriculum/interface";
import { Activity } from "../index/index";
import { Throttle, checkLocation } from "../../utils/util";
import { activitySignRes, checkCourseType, courseSignRes, _checkLocation } from "./util";
const app = getApp<IAppOption>();
const throttle = Throttle();
// pages/signIn/signIn.ts
var amapFile = require('../../libs/amap-wx.130');
Page({

    /**
     * 页面的初始数据
     */
    data: {
        //课程与活动签到共用
        signDetail: {} as signDetail,
        myLocation: {} as any,
        markers: '' as any,
        is_signed: false as Boolean,
        sr_id: 0 as number | string,
        other_type: '' as '课程' | '活动',
        //课程需要的额外参数
        startDate: app.globalData.startDate as string,//学期开始日期
        nowWeeks: app.globalData.nowWeeks as number,//第几周
        course_msg: {} as Course,
        activity_msg: {} as Activity,
        //签到签退开始时间结束时间
        sign_start: '' as string,
        sign_end: '' as string,
        signout_start: '' as string,
        signout_end: '' as string,
        gettingLocation: false as boolean,//是否正在获取地理位置
        marker: [],//
        circles: [{
            latitude: 0 as number,
            longitude: 0 as number,
            color: '#ff4163',
            fillColor: '#7cb5ec88',
            radius: 400,
            strokeWidth: 2
          }],
    },
    /**
     * @funciton 签到
     */
    signIn: async function () {
        //课程
        if (this.data.other_type == '课程') {
            this._CourseSign();
        }
        else if (this.data.other_type == '活动') {//活动
            this._ActicitySign();
        }
    },
    //检查课程签到
    _CourseSign: async function () {
        if(!checkCourseType(this.data.course_msg.type))return;
        //检查是否在签到时间 是否迟到
        let data = this.checkCourseSignInValid();
        //console.log('data=',data);
        if (data.statu == false) return false;
        if (!await _checkLocation(this, this.data.signDetail).then((res) => { return true }).catch((res: any) => { console.log('reject!', res); return false; })) return;
        let courseMsg = this.data.course_msg;
        let user = new User;
        await SignIn({ sr_id: courseMsg.sr_id, name: user.name, code: user.code, week: this.data.nowWeeks, type: '正常签到', s_type: this.data.other_type })
            .then((res: any) => { courseSignRes(res); })
        return true;
    },
    //活动检查签到
    _ActicitySign: async function () {
        let signDetail = this.data.signDetail;
        let statu: any = this.checkSignInStatus(signDetail.start_time, signDetail.end_time, signDetail.sign_start, signDetail.sign_end);
        if (statu != '正常签到' && statu != '迟到') {
            msg.show(statu, '');
            return false;
        }
        if (!await _checkLocation(this, signDetail).then((res) => { return true }).catch((res: any) => { console.log('reject!', res); return false; })) return;
        let activityMsg = this.data.activity_msg;
        let user = new User;
        await SignIn({ sr_id: activityMsg.sr_id, name: user.name, code: user.code, week: this.data.nowWeeks, type: statu, s_type: this.data.other_type })
            .then((res: any) => {
                activitySignRes(res);
            });
    },
    _checkLocation: async function (self: any) {
        //检查是否在签到半径
        let signDetail: signDetail = self.data.signDetail;
        return new Promise(async (resolve, reject) => {
            if (self.data.gettingLocation) {
                console.log('正在获取地理位置信息，请勿重复点击');
                reject('正在获取地理位置信息，请勿重复点击');
            }
            self.setData({
                gettingLocation: true,
            });
            msg.Loading('获取地理位置中');
            let location_res = await checkLocation(signDetail.location.latitude, signDetail.location.longitude, signDetail.radius)
                .then((res: any) => {
                    msg.hideLoading();
                    return res;
                })
                .catch((err) => {
                    msg.hideLoading();
                    msg.show('获取位置信息失败', '请重试');
                });
            self.setData({
                gettingLocation: false,
            });
            if (location_res.res == false || !location_res.res) {
                reject('位置不在签到范围内:' + location_res.distance);
            }
            resolve(location_res.distance);
        })
    },
    //设置签到点
    _setMarker(lat: number, lng: number) {
        const marker = {
            id: 0,
            width: '30px',
            height: '40px',
            latitude: lat,
            longitude: lng,
            label: {
                content: '签到点',  //文本
                color: '#FF0202',  //文本颜色
                borderRadius: 3,  //边框圆角
                borderWidth: 1,  //边框宽度
                borderColor: '#FF0202',  //边框颜色
                bgColor: '#ffffff',  //背景色
                padding: 5,  //文本边缘留白
                textAlign: 'center'  //文本对齐方式。有效值: left, right, center
            },
        }
        this.setData({ ['marker[0]']: marker });
    },
    _setCircle(){
        console.log('serCircle');
        let signDetail=this.data.signDetail;
        let circles = this.data.circles;
        circles[0].latitude=signDetail.location.latitude;
        circles[0].longitude=signDetail.location.longitude;
        circles[0].radius=signDetail.radius;
        this.setData({
            circles:circles,
        });
    },
    init: async function () {
        //初始化签到点
        let signDetail = this.data.signDetail;
        this._setMarker(signDetail.location.latitude, signDetail.location.longitude);
        this._setCircle();
        //初始化定位点
        wx.showLoading({
            title: '定位中，请稍等',
        });
        let location: any = await this.getMyLocation().then((res: any) => { return res; });
        this.setData({ myLocation: location });
        wx.hideLoading();

    },
    onClickLeft() {
        wx.navigateBack();
    },
    /**
     * 生命周期函数--监听页面加载 需传入课程或活动的id
     */
    onLoad: async function (option: any) {
        let nowWeeks = app.globalData.nowWeeks;
        let startDate = app.globalData.startDate;
        this.setData({
            nowWeeks: nowWeeks,
            startDate: startDate,
        });
        //
        if (option.sign_type == '课程') {//课程的情况
            let s_option: SignParamCourse = option;
            let course_msg: Course = JSON.parse(option.course_msg);
            let signDetail: signDetail = this.getCourseTime(course_msg);
            this.setData({
                sr_id: s_option.sr_id,
                other_type: s_option.sign_type,
                course_msg: course_msg,
                signDetail: signDetail,
            });
            this._setMarker(signDetail.location.latitude, signDetail.location.longitude);
            this._setCircle();
        }
        else if (option.sign_type == '活动') {
            let s_option: SignParamActivity = option;
            let activity_msg: Activity = JSON.parse(option.activity_msg);
            let signDetail: signDetail = this.getActivityTime(activity_msg);
            this.setData({
                sr_id: s_option.sr_id,
                other_type: s_option.sign_type,
                activity_msg: activity_msg,
                signDetail: signDetail,
            });
            this._setMarker(signDetail.location.latitude, signDetail.location.longitude);
        }
    },

    getMyLocation() {
        return new Promise((resolve, reject) => {
            let myAmapFun = new amapFile.AMapWX({ key: '1ad54dc313a0320dcddaecf63322f9f4' });
            myAmapFun.getRegeo({
                success: function (data: any) {
                    //成功回调
                    resolve(data[0]);
                },
                fail: function (info: any) {
                    //失败回调
                    reject(info);
                }
            });
        })
    },

    //进行经纬度转换为距离的计算
    Rad(d: number) {
        return d * Math.PI / 180.0;//经纬度转换成三角函数中度分表形式。
    },
    //计算距离，参数分别为第一点的纬度，经度；第二点的纬度，经度
    GetDistance(lat1: number, lat2: number, lng1: number, lng2: number) {
        var radLat1 = this.Rad(lat1);
        var radLat2 = this.Rad(lat2);
        var a = radLat1 - radLat2;
        var b = this.Rad(lng1) - this.Rad(lng2);
        var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
            Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * 6378.137;// EARTH_RADIUS;
        s = Math.round(s * 10000) / 10; //输出为米
        return s;
    },

    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady() {

    },
    //获取课程下一次签到日期
    getNextCourseDate(signDetail: signDetail) {

    },
    //获取签到签退的开始结束时间
    _getSignTime(signDetail: signDetail) {

    },
    /**
     * 生命周期函数--监听页面显示
     */
    onShow: async function () {
        //this.getMyLocation().then((res:any)=>{console.log(res)});
        //获取签到详情 现在不用了
        msg.Loading('获取签到详情中');
        /*
        if (this.data.sr_id == 0) {
          msg.hideLoading();
          msg.show('程序错误', '非法的参数');
          return;
        }
        await GetSignDetail({ sr_id: this.data.sr_id, other_type: this.data.other_type })
          .then((res: any) => {
            if (this.data.other_type == '课程')
              this.setData({
                signDetail: this.getCourseTime(res.data.data),
              });
            else
              this.setData({
                signDetail: res.data.data,
              });
          })
          .catch((res: any) => {
            console.log(res);
            msg.show('获取签到详情失败', '正在返回');
            setTimeout(function () {
              wx.navigateBack();
            }, 1000);
          });*/
        msg.hideLoading();
    },
    /**
     * 生命周期函数--监听页面隐藏
     */
    onHide() {

    },

    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload() {

    },

    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh() {

    },

    /**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom() {

    },

    /**
     * 用户点击右上角分享
     */
    onShareAppMessage() {

    },
    //返回加减去分钟数之后的日期 暂时没用
    _subtractMinutesFromDate(date: string, minutes: string, type: 'add' | 'minus'): string {
        // 将浮点数转换为整数
        let minute = Math.floor(parseInt(minutes));

        // 将日期字符串转换为 Date 对象
        const currentDate = new Date(date);

        // 计算减去分钟数之后的日期
        if (type == 'add')
            currentDate.setMinutes(currentDate.getMinutes() + minute);
        else
            currentDate.setMinutes(currentDate.getMinutes() - minute);
        // 返回新日期的字符串格式
        return currentDate.toISOString();
    },
    /**
    * @function 获取今天是周几
    */
    _getDay(): string {
        const today = new Date().getDay();
        let chineseNumber = '';
        switch (today) {
            case 1:
                chineseNumber = '一';
                break;
            case 2:
                chineseNumber = '二';
                break;
            case 3:
                chineseNumber = '三';
                break;
            case 4:
                chineseNumber = '四';
                break;
            case 5:
                chineseNumber = '五';
                break;
            case 6:
                chineseNumber = '六';
                break;
            case 0:
                chineseNumber = '七';
                break;
        }
        // 因为返回值范围是 0-6，需要将星期天（0）转换为 7
        return chineseNumber;
    },
    //获取课程的开始时间与结束时间,在前端显示
    getCourseTime(course_msg: Course): signDetail {
        let signDetail: signDetail = course_msg.signDetail;
        let times = course_msg.time.split(',');

        let time = '';
        times.forEach((item) => {
            let temp = course_msg.time.split('-');
            time += this._getCourseStartTime(temp[0]) + '-' + this._getCourseEndTime(temp[1]) + '';
        });
        signDetail.start_time = "第" + course_msg.week + '周 星期' + course_msg.day + ' ' + time;
        return signDetail;
    },
    //获取活动的开始时间与结束时间,在前端显示
    getActivityTime(activity_msg: Activity): signDetail {
        let signDetail: signDetail = activity_msg.signDetail;
        signDetail.start_time = activity_msg.a_start;
        signDetail.end_time = activity_msg.a_end;
        return signDetail;
    },
    /**
    * @function 获取上课时间
    */
    _getCourseStartTime(index: string) {
        let time = '';
        switch (index) {
            case '1':
                time = '8:30';
                break;
            case '2':
                time = '9:20';
                break;
            case '3':
                time = '10:20';
                break;
            case '4':
                time = '11:10';
                break;
            case '5':
                time = '14:30';
                break;
            case '6':
                time = '15:20';
                break;
            case '7':
                time = '16:10';
                break;
            case '8':
                time = '16:50';
                break;
            case '9':
                time = '19:00';
                break;
            case '10':
                time = '19:50';
                break;
            case '11':
                time = '20:40';
                break;
        };
        return time;
    },
    /**
     * @function 获取下课时间
     */
    _getCourseEndTime(index: string) {
        let time = '';
        //console.log('endtimeindex=', index);
        switch (index) {
            case '2':
                time = '10:00';
                break;
            case '3':
                time = '11:00';
                break;
            case '4':
                time = '11:50';
                break;
            case '5':
                time = '15:10';
                break;
            case '6':
                time = '16:00';
                break;
            case '7':
                time = '16:50';
                break;
            case '8':
                time = '17:40';
                break;
            case '9':
                time = '19:40';
                break;
            case '10':
                time = '20:30';
                break;
            case '11':
                time = '21:20';
                //console.log('index=11');
                break;
        };
        return time;
    },
    /**
     * @function 判断课程是否能签到并返回信息
     * @return false | '正常签到' | '迟到'
     */
    checkCourseSignInValid(): { statu: false | '正常签到' | '迟到', title: string, content: string } {
        let nowWeeks: number = this.data.nowWeeks;
        let today: string = this._getDay();
        let course_msg = this.data.course_msg;
        let signDetail = this.data.signDetail;
        if (this._checkRange(course_msg.weeks, nowWeeks.toString()) && today == course_msg.day) {
            //课程星期几与今日星期几相符
            //检查是否在签到时间内
            let times = course_msg.time.split('-');
            let timerange = this._getCourseStartTime(times[0]) + '-' + this._getCourseEndTime(times[1]);
            //返回更详细的信息，如迟到,正常签到,签到时间已过
            return this._checkSignStatus(timerange, signDetail.sign_start,signDetail.sign_late_start ,signDetail.sign_end);
        }
        else msg.show('这节课今天不上哦', '请在当天签到');
        return { statu: false, title: '', content: '' };
    },
    /**
    * @function 检查这一周这门课上不上
    */
    _checkRange(range: string, number: string): boolean {
        let ranges = range.split(",");
        let res = false;
        ranges.forEach((item) => {
            let [start, end] = item.split("-").map(Number);
            let num = Number(number);
            if (Number.isNaN(start) || Number.isNaN(end) || Number.isNaN(num)) {
                throw new Error("Invalid input");
            }
            if (num >= start && num <= end) {
                res = true;
            }
        })
        return res;
    },
    /**
    * @function 检查是否在课程正常签到时间内并返回相关信息 在checkCourseSignInValid里被调用
    */
    _checkSignStatus(timeRange: string, minutesBefore: number, minutesLate: number,minutesEnd:number): { statu: false | '正常签到' | '迟到', title: string, content: string } {
        const currentTime = new Date();
        // Split the time range into start time and end time
        const [startTime, endTime] = timeRange.split('-').map(time => {
            const [hours, minutes] = time.split(':').map(Number);
            return new Date(currentTime.getFullYear(), currentTime.getMonth(), currentTime.getDate(), hours, minutes);
        });

        // Calculate the time ranges for early sign-in and late arrival
        //签到开始时间
        const earlySignInStart = new Date(startTime.getTime() - minutesBefore * 60000);
        //迟到开始时间
        const earlySignInEnd = new Date(startTime.getTime() + minutesLate * 60000);
        //签到结束时间
        const signEnd=new Date(startTime.getTime() + minutesEnd * 60000);
        //console.log('minutesLate=',minutesLate);
        if (currentTime >= earlySignInStart && currentTime <= earlySignInEnd) {
            return { statu: "正常签到", title: "签到成功！", content: '' };
        } else if (currentTime >= earlySignInEnd && currentTime <= signEnd) {
            //console.log('迟到');
            return { statu: "迟到", title: "签到成功！", content: '但是迟到了...' };
        } else if (currentTime > signEnd) {
            let end_Minutes = signEnd.getMinutes().toString();
            if (signEnd.getMinutes() < 10) end_Minutes = '0' + end_Minutes;
            msg.show("签到时间已过", '最晚签到时间: ' + signEnd.getHours() + ':' + end_Minutes);
            return { statu: false, title: "签到时间已过", content: '最晚签到时间: ' + endTime.getHours() + ':' + end_Minutes };
        } else if (currentTime < earlySignInStart) {
            let end_Minutes = earlySignInStart.getMinutes().toString();
            if (earlySignInStart.getMinutes() < 10) end_Minutes = '0' + end_Minutes;
            msg.show("还没到签到时间", '最早签到时间: ' + earlySignInStart.getHours() + ':' + end_Minutes);
            return { statu: false, title: "还没到签到时间", content: '最早签到时间: ' + earlySignInStart.getHours() + ':' + end_Minutes };
        }
        return { statu: false, title: '', content: '' };
    },
    //检查活动签到范围
    checkSignInStatus(startTime: string, endTime: string, beforeMinutes: number, afterMinutes: number): string {
        const currentTime = new Date(); // 获取当前时间
        const start = new Date(startTime); // 将活动开始时间字符串转换为日期对象
        const end = new Date(endTime); // 将活动结束时间字符串转换为日期对象

        const signInStart = new Date(start.getTime() - beforeMinutes * 60000); // 计算活动开始前的时间点
        const signInEnd = new Date(start.getTime() + afterMinutes * 60000); // 计算活动开始后的时间点

        if (currentTime >= signInStart && currentTime <= signInEnd) {
            return '正常签到';
        } else if (currentTime > signInEnd && currentTime <= end) {
            return '迟到';
        } else if (currentTime > end) {
            return '签到时间已过';
        } else if (currentTime < signInStart) {
            return '未到签到时间';
        }
        return '不在签到时间';
    },
    //显示如何请假
    showHowToAskForLeave: async function () {
        if (this.data.other_type == '课程') {
            await msg.confirm('课程请假流程取决于各年级辅导员，请了解流程后再发送申请', '点击"确认"跳转申请页面');
            wx.navigateTo({
                url: '/pages/user/leave/leave',
            })
        }
        else
            msg.show('活动请假流程为:', '上线找辅导员或者学生干部请假同意即可(记得保留聊天截图)');
    }
})